const fs = require('fs')
const path = require('path')
const glob = require("glob")
const chokidar = require('chokidar')
const Koa = require('koa')
const serve = require('koa-static-server')
const websockify = require('koa-websocket')
const less = require('less')

const port = 4600
const url = `http://localhost:${port}`
const app = websockify(new Koa())
const clients = new Set()

app.use(serve({ rootDir: 'dist', rootPath: '/' }))

app.ws.use(function (ctx, next) {
  clients.add(ctx.websocket)
  ctx.websocket.onclose = () => {
    clients.delete(ctx.websocket)
  }
  return next(ctx)
})

const renderLess = async (lessFilePath) => {
  let lessFileContent = fs.readFileSync(lessFilePath, { encoding: 'utf-8' })
  let lessRenderRes = await less.render(lessFileContent)

  let targetPath = path.join(__dirname, '../dist', lessFilePath.substring('src/'.length, lessFilePath.length))
  let targetDir = path.dirname(targetPath)
  let targetName = path.basename(targetPath, '.less') + '.css'
  if (!fs.existsSync(targetDir)) {
    fs.mkdirSync(targetDir, { recursive: true })
  }
  targetPath = path.join(targetDir, targetName)
  fs.writeFileSync(targetPath, lessRenderRes.css, { encoding: 'utf-8' })
  return { path: targetPath.replace(path.join(__dirname, '../dist'), '') }
}

const watchAndRenderLess = () => {
  glob("src/**/*.less", {}, function (er, files) {
    files.forEach(renderLess)
  })
  const watcher = chokidar.watch("src/**/*.less")
  watcher.on('all', async (e, filePath, stats) => {
    if (e == 'add' || e == 'change' || e == 'addDir') {
      let result = await renderLess(filePath)
      console.log(`${url}${result.path}`)
      refresh(result.path)
    }
  })
}

const renderClientJs = () => {
  let content = fs.readFileSync(path.join(__dirname, 'client.js'), { encoding: 'utf-8' })
  content = content.replace(/\$\[port\]/g, port)
  fs.writeFileSync(path.join(__dirname, '../dist', 'client.js'), content, { encoding: 'utf-8' })

}

const refresh = (filePath) => {
  clients.forEach((client) => {
    let data = { type: 'refresh', path: filePath }
    client.send(JSON.stringify(data))
  })
}


renderClientJs()
//TODO 还未处理dist多余文件问题
watchAndRenderLess()

app.listen(port)
console.log(url)
console.log(`${url}/client.js`)